package cn.njupt;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Test {

    private static Graph.WeightManager<Double> weightManager=new Graph.WeightManager<Double>() {
        @Override
        public int compare(Double e1, Double e2) {
            return e1.compareTo(e2);
        }

        @Override
        public Double add(Double w1, Double w2) {
            return w1+w2;
        }
    };
    public static void main(String[] args) {
//        ListGraph<String,Integer> graph=new ListGraph<>();
//        graph.addEdge("v1","v0",9);
//        graph.addEdge("v1","v2",3);
//        graph.addEdge("v2","v0",2);
//        graph.addEdge("v2","v3",5);
//        graph.addEdge("v0","v4",6);
//        graph.addEdge("v3","v4",1);
//        graph.addVertex("v5");
//        graph.removeEdge("v1","v0");
//        graph.print();
//        bfs4();
//        bfs1();
//        topo();
//        testMst();
        testShortestPath();

    }
    static void testShortestPath() {
        Graph<Object, Double> graph = directedGraph(Data.SP);
        Map<Object, Graph.PathInfo<Object,Double>> pathes= graph.shortestPath("A");

        pathes.forEach((Object v,Graph.PathInfo<Object,Double> pathInfo)->{
            System.out.println(v+":"+pathInfo);
        });
    }

    static void testMst() {
        Graph<Object, Double> graph = undirectedGraph(Data.MST_02);
        Set<Graph.EdgeInfo<Object, Double>> infos = graph.mst();
        for (Graph.EdgeInfo<Object, Double> info : infos) {
            System.out.println(info);
        }
    }
    public static void topo(){
        Graph<Object,Double> graph=directedGraph(Data.TOPO);
        List<Object> list=graph.topologicalSort();
        list.forEach(o -> System.out.println(o));

    }

    public static void bfs1(){

        Graph<Object,Double> graph=undirectedGraph(Data.BFS_01);
        graph.bfs("A",new Graph.Visitor<Object>() {
            @Override
            public boolean visit(Object o) {
                System.out.println(o);
                if(o.equals("E"))return true;
                return false;
            }
        });
    }

    public static void bfs2(){
        Graph<Object,Double> graph=directedGraph(Data.BFS_02);
        graph.bfs(0, new Graph.Visitor<Object>() {
            @Override
            public boolean visit(Object o) {
                System.out.println(o);
                return false;
            }
        });
    }

    public static void bfs3(){
        Graph<Object,Double> graph=undirectedGraph(Data.BFS_03);
        graph.bfs(0,new Graph.Visitor<Object>() {
            @Override
            public boolean visit(Object o) {
                System.out.println(o);
                return false;
            }
        });
    }

    public static void bfs4(){
        Graph<Object,Double> graph=directedGraph(Data.BFS_04);
        graph.bfs(5,new Graph.Visitor<Object>() {
            @Override
            public boolean visit(Object o) {
                System.out.println(o);
                return false;
            }
        });
    }

    public static void dfs1(){
        Graph<Object,Double> graph=undirectedGraph(Data.DFS_01);
        graph.dfs(1);
    }

    public static void dfs2(){
        Graph<Object,Double> graph=directedGraph(Data.DFS_02);
        graph.dfs("a");
    }
    public static Graph<Object,Double> directedGraph(Object[][] obj){
        Graph<Object,Double> graph=new ListGraph<>(weightManager);
        for (Object[] objects:obj){
            if(objects.length==1){
                //添加顶点
                graph.addVertex(objects[0]);
            }else if(objects.length==2){
                //添加边
                graph.addEdge(objects[0],objects[1]);
            }else{
                //添加有权值的边
                graph.addEdge(objects[0],objects[1],Double.parseDouble(objects[2].toString()));
            }
        }
        return graph;
    }

    public static Graph<Object,Double> undirectedGraph(Object[][] obj){

        Graph<Object,Double> graph=new ListGraph<>(weightManager);
        for (Object[] objects:obj){
            if(objects.length==1){
                //添加顶点
                graph.addVertex(objects[0]);
            }else if(objects.length==2){
                //添加边
                graph.addEdge(objects[0],objects[1]);
                graph.addEdge(objects[1],objects[0]);
            }else{
                //添加有权值的边
                graph.addEdge(objects[0],objects[1],Double.parseDouble(objects[2].toString()));
                graph.addEdge(objects[1],objects[0],Double.parseDouble(objects[2].toString()));
            }
        }
        return graph;
    }





}
